package com.lovo.shiro;

import com.lovo.result.Result;
import com.lovo.result.ResultCode;
import com.lovo.service.IUserInfoService;
import com.lovo.util.WebUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class RestAuthorizationFilter  extends PermissionsAuthorizationFilter {
    @Resource
    private IUserInfoService userInfoService;

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = this.getSubject(request, response);
        try{
            subject.login(new JWTToken(((HttpServletRequest)request).getHeader("token")));
        }catch (AuthenticationException e){
            return false;
        }
        String[] perms = (String[])mappedValue;
        boolean isPermitted = true;
        if (perms != null && perms.length > 0) {
            if (perms.length == 1) {
                if (!subject.isPermitted(perms[0])) {
                    isPermitted = false;
                }
            } else if (!subject.isPermittedAll(perms)) {
                isPermitted = false;
            }
        }

        return isPermitted;
    }

    @Override
    protected boolean pathsMatch(String path, ServletRequest request) {
        String requestURI = this.getPathWithinApplication(request);
        String[] strings = path.split("==");
        if (strings.length <= 1) {
            // 普通的 URL, 正常处理
            return this.pathsMatch(strings[0], requestURI);
        } else {
            // 获取当前请求的 http method.
            String httpMethod = WebUtils.toHttp(request).getMethod().toUpperCase();
            // 匹配当前请求的 http method 与 过滤器链中的的是否一致
            return httpMethod.equals(strings[1].toUpperCase()) && this.pathsMatch(strings[0], requestURI);
        }
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = getSubject(request, response);
        // 如果未登录
        if(subject.getPrincipal() == null){
            WebUtil.writeValueAsString(response, Result.fail(ResultCode.USER_AUTHENTICATION_ERROR));
        } else {
            WebUtil.writeValueAsString(response, Result.fail(ResultCode.USER_AUTHORIZATION_ERROR));
        }
        return false;
    }


}
